﻿using System;
using System.Text;
using System.Drawing;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static partial class glDRIVE
{
    /*
    函数 gl.ngin
    非线性方程组最小二乘解
    f(int m,int n,double[] x, double[] p)计算非线性方程组各方程左端函数值的函数名。
    s(int m,int n,double[] x, double[] p)计算雅可比矩阵的函数名。
    参数 m: 非线性方程组中方程个数。
    参数 n: 非线性方程组中未知数个数。m>=n。
    参数 eps1: 控制最小二乘解的精度要求。
    参数 eps2: 奇异值分解中的控制精度要求
    参数 x: x[n]存放初始近似值。返回最小二乘解，当m=n时即为非线性方程组的解。
    返回值 函数返回迭代次数。本函数最大迭代次数为100。若迭代次数<0则表示奇异值分解失败。
    */

    public static unsafe string drive_ngin()
    {
        int m, n, i;
        double eps1, eps2;
        double[] x = new double[2] { 0.5, -1.0 };

        m = 2;
        n = 2;
        eps1 = 0.000001;
        eps2 = 0.000001;
        gl.f_xa_ya_mn = nginf;
        gl.s_xa_ya_mn = ngins;
        i = gl.ngin(m, n, eps1, eps2, x);

        return gl.html_table("迭代次数=" + i, x);
    }

    // 计算非线性方程组各方程左端函数值
    private static unsafe double nginf(double* x, double* d, int m, int n)
    {
        //m = m; n = n;
        d[0] = x[0] * x[0] + 10.0 * x[0] * x[1] + 4.0 * x[1] * x[1] + 0.7401006;
        d[1] = x[0] * x[0] - 3.0 * x[0] * x[1] + 2.0 * x[1] * x[1] - 1.0201228;
        return 0;
    }

    // 计算雅可比矩阵
    private static unsafe double ngins(double* x, double* p, int m, int n)
    {
        //m = m;
        //p[0, 0]
        p[0 * n + 0] = 2.0 * x[0] + 10.0 * x[1];
        //p[0, 1]
        p[0 * n + 1] = 10.0 * x[0] + 8.0 * x[1];
        //p[1, 0]
        p[1 * n + 0] = 2.0 * x[0] - 3.0 * x[1];
        //p[1, 1]
        p[1 * n + 1] = -3.0 * x[0] + 4.0 * x[1];
        return 0;
    }
}
